package com.nulldev.util.web.HttpServer3.extensions.nCaptcha.backend;

import com.nulldev.util.languages.json.uniapi.UniJsonValue;
import com.nulldev.util.web.HttpServer3.Response;
import com.nulldev.util.web.HttpServer3.extensions.nCaptcha.nCaptcha;
import com.nulldev.util.web.HttpServer3.extensions.nCaptcha.backend.user.User;
import com.nulldev.util.web.HttpServer3.extensions.nCaptcha.backend.util.UUIDCookieLoader;
import com.nulldev.util.web.HttpServer3.legacyPages.v1.RequestType;
import com.nulldev.util.web.HttpServer3.pages.v3.HttpPage3;
import com.nulldev.util.web.URLUtils.URLQueryParser;

public class CheckCaptcha extends HttpPage3 {

	private static final String JSON_MIME = "application/json; charset=utf-8";

	public CheckCaptcha() {
		super("/captcha/check_captcha", true);
		super.setCachingMethod(CachingMethod.NO_CACHE);
	}

	@SuppressWarnings("resource")
	@Override
	public Response onRequest(final Request request) {
		if (!request.getType().equals(RequestType.POST)) {
			if (nCaptcha.NCAPTCHA_ENABLE_DEBUGGING) {
				return new Response(405, createStream(UniJsonValue.object(2).add("error", true).add("reason", "NCAPTCHA_INVALID_REQUEST_TYPE").toString()))
						.setCustomMime(JSON_MIME);
			} else {
				return new Response(405);
			}
		}

		if (!request.hasInputStream()) {
			if (nCaptcha.NCAPTCHA_ENABLE_DEBUGGING) {
				return new Response(411, createStream(UniJsonValue.object(2).add("error", true).add("reason", "NCAPTCHA_POST_DATA_MISSING").toString()))
						.setCustomMime(JSON_MIME);
			} else {
				return new Response(411);
			}
		}

		final User user = UUIDCookieLoader.userFromRequest(request);
		if (user == null) {
			if (nCaptcha.NCAPTCHA_ENABLE_DEBUGGING) {
				return new Response(400, createStream(UniJsonValue.object(2).add("error", true).add("reason", "NCAPTCHA_USER_NOT_FOUND").toString()))
						.setCustomMime(JSON_MIME);
			} else {
				return new Response(400);
			}
		}

		final boolean isLegacy;
		final String body = toString(request.getInputStream());
		final String input;

		if (request.header("Content-Type", "null").equals("application/x-www-form-urlencoded")) {
			input = URLQueryParser.extract(body).get("value");
			isLegacy = true;
		} else {
			if (!body.startsWith("{") && !body.endsWith("}")) {
				return new Response(400);
			}

			final UniJsonValue object = UniJsonValue.parse(body);
			input = object.getString("value", null);
			isLegacy = false;
		}
		final UniJsonValue response = UniJsonValue.object(2);
		response.add("uuid", user.uuid());

		if (input == null || input.isEmpty()) {
			user.captchaFailed();
			response.add("result", "failed");
			return new Response(406, response, response).setCustomMime(JSON_MIME);
		}

		if (user.getExpectedResults() == null || user.getExpectedResults().length == 0 || input == null) {
			user.captchaFailed();
			response.add("result", "failed");
			return new Response(406, response, response).setCustomMime(JSON_MIME);
		}

		final boolean passed = user.validExpectedResult(input);
		if (passed) {
			user.captchaPassed();
		} else {
			user.captchaFailed();
		}

		if (isLegacy) {
			if (passed) {
				return new Response(302, blankStream()).header("Location", "/captcha/challenge-passed");
			} else {
				return new Response(302, blankStream()).header("Location", "/captcha/challenge-cooldown-short");
			}
		} else {
			if (passed) {
				response.add("result", "passed");
				return new Response(200, response, response).setCustomMime(JSON_MIME);
			} else {
				response.add("result", "failed");
				return new Response(406, response, response).setCustomMime(JSON_MIME);
			}
		}
	}
}
